﻿using ETask.Api.Dtos;
using ETask.Api.Mappers;
using ETask.Api.Models;
using ETask.Api.Repositories;

namespace ETask.Api.Services
{
    public class DeptService : GenericService<Dept, DeptDto, CreateDeptDto, UpdateDeptDto>, IDeptService
    {

        private readonly IDeptRepository _deptRepository;

        public DeptService(IDeptRepository repository, GenericMapper<Dept, DeptDto, CreateDeptDto, UpdateDeptDto> mapper) : base(repository, mapper)
        {
            _deptRepository = repository;
        }

        public async Task<ApiResponse> AddDept(CreateDeptDto deptDto)
        {
            if (deptDto == null)
            {
                return ApiResponse.Fail(400, "部门信息不能为空");
            }
            var allDepts = await _deptRepository.FindAllAsync(q=>!string.IsNullOrWhiteSpace(q.DeptName));
            string newDeptCode;
            if (string.IsNullOrWhiteSpace(deptDto.ParentDeptCode))
            {
                var maxTopDeptCode = allDepts
                    .Where(d => d.DeptCode.Length == 3)
                    .Select(d => d.DeptCode)
                    .DefaultIfEmpty("000")
                    .Max();

                if (int.TryParse(maxTopDeptCode, out int maxCode))
                {
                    newDeptCode = (maxCode + 1).ToString("D3"); 
                }
                else
                {
                    return ApiResponse.Fail(400, "现有部门编码格式错误，无法生成新编码");
                }
            }
            else
            {
                var parentDept = allDepts.FirstOrDefault(d => d.DeptCode == deptDto.ParentDeptCode);
                if (parentDept == null)
                {
                    return ApiResponse.Fail(404, "指定的父部门不存在");
                }

                var childDepts = allDepts
                    .Where(d => d.DeptCode.StartsWith(deptDto.ParentDeptCode) && !d.DeptCode.Equals(deptDto.ParentDeptCode))
                    .ToList();

                var parentCode = deptDto.ParentDeptCode;
                var maxChildCode = childDepts
                    .Select(d => d.DeptCode)
                    .DefaultIfEmpty($"{parentCode}000")
                    .Max();

                if (maxChildCode.Length >= parentCode.Length + 3 &&
                    int.TryParse(maxChildCode.Substring(parentCode.Length), out int maxChildNum))
                {
                    newDeptCode = $"{parentCode}{(maxChildNum + 1).ToString("D3")}";
                }
                else
                {
                    return ApiResponse.Fail(400, "现有子部门编码格式错误，无法生成新编码");
                }
            }
            if (allDepts.Any(d => d.DeptCode == newDeptCode))
            {
                return ApiResponse.Fail(400, "部门编码已存在，请稍后重试");
            }
            deptDto.DeptCode = newDeptCode;
            await CreateAsync(deptDto);
            return ApiResponse.Ok("部门添加成功");
        }

        public async Task<ApiResponse> DelById(int id)
        {
            await DeleteAsync(id);
            return ApiResponse.Ok("删除成功");
        }

        public async Task<ApiResponse> GetList(DeptListParams listParams)
        {
            var result = await _deptRepository.GetListAsync(listParams);
            result.Items = result.Items.Select(q =>
            {
                if (q.DeptCode.Length>3)
                {
                    q.ParentDeptCode = q.DeptCode.Substring(0, q.DeptCode.Length - 3);
                }
                return q;
            }).ToList();

            return ApiResponse.Ok(result);
        }

        public async Task<ApiResponse> GetTree()
        {
            var deptList = await _deptRepository.FindAllAsync(q=>!string.IsNullOrEmpty(q.DeptName));
            var rootList = deptList.Where(q => q.DeptCode.Length == 3).ToList();
            var treeList = rootList.Select(q => new DeptDto
            {
                Id = q.Id,
                DeptName = q.DeptName,
                DeptCode = q.DeptCode,
                ParentDeptCode = null,
                CreatedAt = q.CreatedAt,
                UpdatedAt = q.UpdatedAt
            }).ToList();
            foreach (var item in treeList)
            {
                item.Children = GetChildDepartments(deptList, item.DeptCode);
            }
            return ApiResponse.Ok(treeList);
        }

        public async Task<ApiResponse> UpdateDept(UpdateDeptDto deptDto)
        {
            await UpdateAsync(deptDto.Id, deptDto);
            return ApiResponse.Ok("更新成功");
        }

        private List<DeptDto> GetChildDepartments(List<Dept> allDepartments, string parentCode)
        {
            var children = allDepartments
                .Where(dept => dept.DeptCode.Length == parentCode.Length + 3
                            && dept.DeptCode.StartsWith(parentCode))
                .Select(dept => new DeptDto
                {
                    Id = dept.Id,
                    DeptName = dept.DeptName,
                    DeptCode = dept.DeptCode,
                    ParentDeptCode = parentCode,
                    CreatedAt = dept.CreatedAt,
                    UpdatedAt = dept.UpdatedAt,
                    Children = GetChildDepartments(allDepartments, dept.DeptCode)
                })
                .ToList();

            return children;
        }
    }
}
